#pragma once

#include "CoreMinimal.h"
#include "Data/MissionEnum.h"
#include "Engine/DataTable.h"
#include "UObject/NoExportTypes.h"
#include "MissionStruct.generated.h"

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FAssignedObjectiveTarget
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool UniqueNameMatters;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FName UniqueName;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TSubclassOf<AActor> TargetClass;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	int32 Amount;

};

FORCEINLINE bool operator==(const FAssignedObjectiveTarget& Elem1, const FAssignedObjectiveTarget& Elem2) {
	return Elem1.UniqueNameMatters == Elem2.UniqueNameMatters&&
		Elem1.UniqueName == Elem2.UniqueName&&
		Elem1.TargetClass == Elem2.TargetClass&&
		Elem1.Amount == Elem2.Amount;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FDirections
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FName Name;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	int32 WorldRotation;

	FDirections() {
		Name = FName();
		WorldRotation = 0;
	}

	FDirections(FName LName, int32 LWorldRotation) {
		Name = LName;
		WorldRotation = LWorldRotation;
	}

};

FORCEINLINE bool operator==(const FDirections& Elem1, const FDirections& Elem2) {
	return Elem1.Name == Elem2.Name&&
		Elem1.WorldRotation == Elem2.WorldRotation;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FFinishedLayout
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool DisplayWidget;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	float DisplayTime;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FLinearColor HeadlineColor;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FLinearColor BorderColor;

};

FORCEINLINE bool operator==(const FFinishedLayout& Elem1, const FFinishedLayout& Elem2) {
	return Elem1.DisplayWidget == Elem2.DisplayWidget&&
		Elem1.DisplayTime == Elem2.DisplayTime&&
		Elem1.HeadlineColor == Elem2.HeadlineColor&&
		Elem1.BorderColor == Elem2.BorderColor;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FFollowIndexInfo
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	float Delay;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	float WalkSpeed;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FVector Location;

};

FORCEINLINE bool operator==(const FFollowIndexInfo& Elem1, const FFollowIndexInfo& Elem2) {
	return Elem1.Delay == Elem2.Delay&&
		Elem1.WalkSpeed == Elem2.WalkSpeed&&
		Elem1.Location == Elem2.Location;
}


USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FHintBase
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	class UMaterialInstance* HintMarker;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TArray<FText> Hints;
};

FORCEINLINE bool operator==(const FHintBase& Elem1, const FHintBase& Elem2) {
	if (Elem1.HintMarker != Elem2.HintMarker || Elem1.Hints.Num() != Elem2.Hints.Num()) return false;
	for (int i = 0; i < Elem1.Hints.Num(); ++i) {
		if (!Elem1.Hints[i].EqualTo(Elem2.Hints[2])) return false;
	}
	return true;
}


USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FMarkerCustomization
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	EMarkerType MarkerType;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FVector MarkerExtraPadding;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	int32 MaxDistanceToShowMarker;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool HideOnScreenEdge;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool HideOnCompassEdge;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool UseMaterialInstance;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool DynamicBackground;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FLinearColor MarkerColor;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FLinearColor IndicatorColor;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FLinearColor BackgroundColor;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FLinearColor DynamicBackgroundColor;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	class UMaterialInstance* MarkerMaterial;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	class UTexture* MarkerTexture;

};

FORCEINLINE bool operator==(const FMarkerCustomization& Elem1, const FMarkerCustomization& Elem2) {
	return Elem1.MarkerType == Elem2.MarkerType&&
		Elem1.MarkerExtraPadding == Elem2.MarkerExtraPadding&&
		Elem1.MaxDistanceToShowMarker == Elem2.MaxDistanceToShowMarker&&
		Elem1.HideOnScreenEdge == Elem2.HideOnScreenEdge&&
		Elem1.HideOnCompassEdge == Elem2.HideOnCompassEdge&&
		Elem1.UseMaterialInstance == Elem2.UseMaterialInstance&&
		Elem1.DynamicBackground == Elem2.DynamicBackground&&
		Elem1.MarkerColor == Elem2.MarkerColor&&
		Elem1.IndicatorColor == Elem2.IndicatorColor&&
		Elem1.BackgroundColor == Elem2.BackgroundColor&&
		Elem1.DynamicBackgroundColor == Elem2.DynamicBackgroundColor&&
		Elem1.MarkerMaterial == Elem2.MarkerMaterial&&
		Elem1.MarkerTexture == Elem2.MarkerTexture;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FMarkerInfo
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	EMarkerType MarkerType;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FName TargetsUniqueName;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FName CustomObjectiveUniqueName;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FVector TargetLocation;

};

FORCEINLINE bool operator==(const FMarkerInfo& Elem1, const FMarkerInfo& Elem2) {
	return Elem1.MarkerType == Elem2.MarkerType&&
		Elem1.TargetsUniqueName == Elem2.TargetsUniqueName&&
		Elem1.CustomObjectiveUniqueName == Elem2.CustomObjectiveUniqueName&&
		Elem1.TargetLocation == Elem2.TargetLocation;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FMissionRestartInfo
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool RestartOnFail;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FVector RestartLocation;
	
};

FORCEINLINE bool operator==(const FMissionRestartInfo& Elem1, const FMissionRestartInfo& Elem2) {
	return Elem1.RestartOnFail == Elem2.RestartOnFail&&
		Elem1.RestartLocation == Elem2.RestartLocation;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FMissionMainInfo
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	ERegion Region;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FText Name;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FText Description;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	int32 SuggestedLevel;

};

FORCEINLINE bool operator==(const FMissionMainInfo& Elem1, const FMissionMainInfo& Elem2) {
	return Elem1.Region == Elem2.Region&&
		Elem1.Name.EqualTo(Elem2.Name)&&
		Elem1.Description.EqualTo(Elem2.Description)&&
		Elem1.SuggestedLevel == Elem2.SuggestedLevel;
}

//=====================================================
USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FNonEditTarget
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TSubclassOf<AActor> ActorClass;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	class AActor* SelfReference;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FVector Location;

};

FORCEINLINE bool operator==(const FNonEditTarget& Elem1, const FNonEditTarget& Elem2) {
	return Elem1.ActorClass == Elem2.ActorClass&&
		Elem1.SelfReference == Elem2.SelfReference&&
		Elem1.Location == Elem2.Location;
}

//=====================================================
USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FObjectiveLayout
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool DisplayInObjectives;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FText ObjectiveTitle;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FHintBase Hints;

};

FORCEINLINE bool operator==(const FObjectiveLayout& Elem1, const FObjectiveLayout& Elem2) {
	return Elem1.DisplayInObjectives == Elem2.DisplayInObjectives&&
		Elem1.ObjectiveTitle.EqualTo(Elem2.ObjectiveTitle)&&
		Elem1.Hints == Elem2.Hints;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FObjectiveMainInfo
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool UniqueNameMatters;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FName TargetsUniqueName;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	int32 Amount;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FVector TargetLocation;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TSubclassOf<AActor> TargetsClass;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FMarkerCustomization MarkerCustomization;


};

FORCEINLINE bool operator==(const FObjectiveMainInfo& Elem1, const FObjectiveMainInfo& Elem2) {
	return Elem1.UniqueNameMatters == Elem2.UniqueNameMatters&&
		Elem1.TargetsUniqueName == Elem2.TargetsUniqueName&&
		Elem1.Amount == Elem2.Amount&&
		Elem1.TargetLocation == Elem2.TargetLocation&&
		Elem1.TargetsClass == Elem2.TargetsClass&&
		Elem1.MarkerCustomization == Elem2.MarkerCustomization;
}


USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FQuestGiverInfo
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	ENPCStatus Status;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	int32 CurrentMissionIndex;

};

FORCEINLINE bool operator==(const FQuestGiverInfo& Elem1, const FQuestGiverInfo& Elem2) {
	return Elem1.Status == Elem2.Status&&
		Elem1.CurrentMissionIndex == Elem2.CurrentMissionIndex;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FRewards
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FText RewardName;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	int32 Amount;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TSubclassOf<AActor> RewardClass;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	class UTexture2D* RewardIcon;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	class UMaterialInstance* RewardIconBackground;
};

FORCEINLINE bool operator==(const FRewards& Elem1, const FRewards& Elem2) {
	return Elem1.RewardName.EqualTo(Elem2.RewardName) &&
		Elem1.Amount == Elem2.Amount&&
		Elem1.RewardClass == Elem2.RewardClass&&
		Elem1.RewardIcon == Elem2.RewardIcon&&
		Elem1.RewardIconBackground == Elem2.RewardIconBackground;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FTargetInfo
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	ETargetType TargetType;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FName TargetUniqueName;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	int32 Amount;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FMarkerCustomization MarkerCustomization;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FNonEditTarget NonEditTargetInfo;
};

FORCEINLINE bool operator==(const FTargetInfo& Elem1, const FTargetInfo& Elem2) {
	return Elem1.TargetType == Elem2.TargetType&&
		Elem1.TargetUniqueName == Elem2.TargetUniqueName&&
		Elem1.Amount == Elem2.Amount&&
		Elem1.MarkerCustomization == Elem2.MarkerCustomization&&
		Elem1.NonEditTargetInfo == Elem2.NonEditTargetInfo;
}



USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FTimerInfo
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	float TimeInSeconds;
};

FORCEINLINE bool operator==(const FTimerInfo& Elem1, const FTimerInfo& Elem2) {
	return Elem1.TimeInSeconds == Elem2.TimeInSeconds;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FDefaultNPCInfo
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	ENPCStatus Status;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FName UniqueName;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	int32 CurrentMissionIndex;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FVector NearestLocation;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FDataTableRowHandle DataTableToUse;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FMarkerCustomization MarkerCustomization;

};


FORCEINLINE bool operator==(const FDefaultNPCInfo& Elem1, const FDefaultNPCInfo& Elem2) {
	return Elem1.Status == Elem2.Status&&
		Elem1.UniqueName == Elem2.UniqueName&&
		Elem1.CurrentMissionIndex == Elem2.CurrentMissionIndex&&
		Elem1.NearestLocation == Elem2.NearestLocation&&
		Elem1.DataTableToUse == Elem2.DataTableToUse&&
		Elem1.MarkerCustomization == Elem2.MarkerCustomization;
}


USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FFollowObjectiveInfo
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool MustBeOnSight;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FTimerInfo TimerOptions;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TArray<FFollowIndexInfo> TargetLocationInfos;

};

FORCEINLINE bool operator==(const FFollowObjectiveInfo& Elem1, const FFollowObjectiveInfo& Elem2) {
	return Elem1.MustBeOnSight == Elem2.MustBeOnSight&&
		Elem1.TimerOptions == Elem2.TimerOptions&&
		Elem1.TargetLocationInfos == Elem2.TargetLocationInfos;
}


USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FOnMissionFinished
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FFinishedLayout WidgetLayout;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FMissionRestartInfo RestartOptions;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TArray<FRewards> Rewards;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FName ActorsToEnable;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TArray<FDataTableRowHandle> QuestsToAdd;

};

FORCEINLINE bool operator==(const FOnMissionFinished& Elem1, const FOnMissionFinished& Elem2) {
	return Elem1.WidgetLayout == Elem2.WidgetLayout&&
		Elem1.RestartOptions == Elem2.RestartOptions&&
		Elem1.Rewards == Elem2.Rewards&&
		Elem1.ActorsToEnable == Elem2.ActorsToEnable&&
		Elem1.QuestsToAdd == Elem2.QuestsToAdd;
}


USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FSpecialObjectives
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FFollowObjectiveInfo FollowObjective;
};

FORCEINLINE bool operator==(const FSpecialObjectives& Elem1, const FSpecialObjectives& Elem2) {
	return Elem1.FollowObjective == Elem2.FollowObjective;
}


USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FObjectives
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	EObjectiveLType ObjectiveClass;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	EObjectiveType SpecificObjectiveType;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FSpecialObjectives SpecialObjectivesInfo;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FObjectiveLayout ObjectiveLayout;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TArray<FObjectiveMainInfo> ObjectiveTargets;
};

FORCEINLINE bool operator==(const FObjectives& Elem1, const FObjectives& Elem2) {
	return Elem1.ObjectiveClass == Elem2.ObjectiveClass&&
		Elem1.SpecificObjectiveType == Elem2.SpecificObjectiveType&&
		Elem1.SpecialObjectivesInfo == Elem2.SpecialObjectivesInfo&&
		Elem1.ObjectiveLayout == Elem2.ObjectiveLayout&&
		Elem1.ObjectiveTargets == Elem2.ObjectiveTargets;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FLocationObjectiveMaster
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FName UniqueLocationName;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TArray<FObjectives> Objectives;

};

FORCEINLINE bool operator==(const FLocationObjectiveMaster& Elem1, const FLocationObjectiveMaster& Elem2) {
	return Elem1.UniqueLocationName == Elem2.UniqueLocationName&&
		Elem1.Objectives == Elem2.Objectives;
}



USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FSequences
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FText SequenceTitle;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FText SequenceDescription;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TArray<FObjectives> Objectives;
};

FORCEINLINE bool operator==(const FSequences& Elem1, const FSequences& Elem2) {
	return Elem1.SequenceTitle.EqualTo(Elem2.SequenceTitle)&&
		Elem1.SequenceDescription.EqualTo(Elem2.SequenceDescription)&&
		Elem1.Objectives == Elem2.Objectives;
}

USTRUCT(BlueprintType)
struct MISCELLANEOUSPROJECT_API FMissionMaster:public FTableRowBase
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool Repeatable;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	EQuestCategoryStatus MissionCategory;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FMissionMainInfo MissionMainInfo;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	TArray<FSequences> Sequences;
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	FOnMissionFinished OnMissionFinished;

};


FORCEINLINE bool operator==(const FMissionMaster& Elem1, const FMissionMaster& Elem2) {
	return Elem1.Repeatable == Elem2.Repeatable&&
		Elem1.MissionCategory == Elem2.MissionCategory&&
		Elem1.MissionMainInfo == Elem2.MissionMainInfo&&
		Elem1.Sequences == Elem2.Sequences&&
		Elem1.OnMissionFinished == Elem2.OnMissionFinished;
}


















